<html>
<head><meta charset="utf-8"><title>Associated type normalization · wg-traits · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/144729-wg-traits/index.html">wg-traits</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/144729-wg-traits/topic/Associated.20type.20normalization.html">Associated type normalization</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="169820332"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/144729-wg-traits/topic/Associated%20type%20normalization/near/169820332" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Florian Diebold <a href="https://rust-lang.github.io/zulip_archive/stream/144729-wg-traits/topic/Associated.20type.20normalization.html#169820332">(Jul 07 2019 at 17:59)</a>:</h4>
<p>So, we added <code>for</code> loop support in rust-analyzer but it's not having the desired effect, and I'm investigating why. There's something weird going on with the rules for normalization, and I'm not sure whether I'm doing something wrong or there's a bug there.</p>
<p>Basically, written as a Chalk test:</p>
<div class="codehilite"><pre><span></span><span class="n">program</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">trait</span><span class="w"> </span><span class="nb">IntoIterator</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="k">type</span> <span class="nc">Item</span><span class="p">;</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="k">trait</span><span class="w"> </span><span class="nb">Iterator</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="k">type</span> <span class="nc">Item</span><span class="p">;</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="k">struct</span> <span class="nb">Vec</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="k">struct</span> <span class="kt">u32</span> <span class="p">{</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="k">impl</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="nb">IntoIterator</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="nb">Vec</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="k">type</span> <span class="nc">Item</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">T</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="k">impl</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="nb">IntoIterator</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">T</span><span class="w"> </span><span class="k">where</span><span class="w"> </span><span class="n">T</span>: <span class="nb">Iterator</span> <span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="k">type</span> <span class="nc">Item</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&lt;</span><span class="n">T</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="nb">Iterator</span><span class="o">&gt;</span>::<span class="n">Item</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="n">goal</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">forall</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="n">exists</span><span class="o">&lt;</span><span class="n">U</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">            </span><span class="n">Normalize</span><span class="p">(</span><span class="o">&lt;</span><span class="nb">Vec</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="nb">IntoIterator</span><span class="o">&gt;</span>::<span class="n">Item</span><span class="w"> </span>-&gt; <span class="nc">U</span><span class="p">)</span><span class="w"></span>
<span class="w">        </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</pre></div>


<p>I'd expect this to have a unique solution (because the <code>Iterator</code> impl shouldn't matter), but it doesn't currently. The problem as far as I understand it is that the <code>impl&lt;T&gt; IntoIterator for T where T: Iterator</code> results in a rule <code>Normalize(&lt;Vec&lt;T&gt; as IntoIterator&gt;::Item -&gt; &lt;Vec&lt;T&gt; as Iterator&gt;::Item) :- Implemented(Vec&lt;T&gt;: IntoIterator)</code>, and then <code>Implemented(Vec&lt;T&gt;: IntoIterator)</code> is of course the case, but because of the other impl. So I don't understand how this is actually supposed to work.</p>



<a name="169838156"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/144729-wg-traits/topic/Associated%20type%20normalization/near/169838156" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Geoffry Song <a href="https://rust-lang.github.io/zulip_archive/stream/144729-wg-traits/topic/Associated.20type.20normalization.html#169838156">(Jul 08 2019 at 03:35)</a>:</h4>
<p>indeed, it seems that the <code>Normalize-From-Impl</code> rule is wrong as written... it only requires that the trait be implemented _at all_, not that the particular impl in question applies</p>



<a name="169838221"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/144729-wg-traits/topic/Associated%20type%20normalization/near/169838221" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Geoffry Song <a href="https://rust-lang.github.io/zulip_archive/stream/144729-wg-traits/topic/Associated.20type.20normalization.html#169838221">(Jul 08 2019 at 03:37)</a>:</h4>
<p>i guess the way to fix it would be to add the bounds of the impl in question to the hypotheses, at which point the <code>Implemented</code> hypothesis wouldn't be needed</p>



<a name="169838277"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/144729-wg-traits/topic/Associated%20type%20normalization/near/169838277" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Geoffry Song <a href="https://rust-lang.github.io/zulip_archive/stream/144729-wg-traits/topic/Associated.20type.20normalization.html#169838277">(Jul 08 2019 at 03:39)</a>:</h4>
<p>it'd be nice to avoid that duplication, but that probably needs impls to be named?</p>



<a name="169855653"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/144729-wg-traits/topic/Associated%20type%20normalization/near/169855653" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Florian Diebold <a href="https://rust-lang.github.io/zulip_archive/stream/144729-wg-traits/topic/Associated.20type.20normalization.html#169855653">(Jul 08 2019 at 10:04)</a>:</h4>
<p>named impls might be useful if they allowed us to find out which impl actually applied? <span aria-label="thinking" class="emoji emoji-1f914" role="img" title="thinking">:thinking:</span></p>



<a name="173990586"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/144729-wg-traits/topic/Associated%20type%20normalization/near/173990586" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Florian Diebold <a href="https://rust-lang.github.io/zulip_archive/stream/144729-wg-traits/topic/Associated.20type.20normalization.html#173990586">(Aug 23 2019 at 18:15)</a>:</h4>
<p>I opened an issue for this and another associated type problem I have: <a href="https://github.com/rust-lang/chalk/issues/234" target="_blank" title="https://github.com/rust-lang/chalk/issues/234">https://github.com/rust-lang/chalk/issues/234</a></p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>